'use strict';

{{ $searchDataFile := printf "%s.search-data.js" .Language.Lang }}
{{ $searchData := resources.Get "search-data.js" | resources.ExecuteAsTemplate $searchDataFile . | resources.Minify}}

(function () {
  const input = document.querySelector('.book-search input');
  const results = document.querySelector('#book-search-results');

  if (!input) {
    return
  }

  input.addEventListener('focus', init);
  input.addEventListener('keyup', search);

  document.addEventListener('keypress', focusSearchFieldOnKeyPress);

  var clearSearchBtn = document.querySelector('.clear-search')
  clearSearchBtn.addEventListener('click', function(){
    document.querySelector('.book-search input').value = ''
    document.querySelector('#book-search-results').innerHTML = ''
    clearSearchBtn.classList.remove('display')
  })

  /**
   * @param {Event} event
   */
  function focusSearchFieldOnKeyPress(event) {
    if (input === document.activeElement) {
      return;
    }

    const characterPressed = String.fromCharCode(event.charCode);
    if (!isHotkey(characterPressed)) {
      return;
    }

    input.focus();
    event.preventDefault();
  }

  /**
   * @param {String} character
   * @returns {Boolean} 
   */
  function isHotkey(character) {
    const dataHotkeys = input.getAttribute('data-hotkeys') || '';
    return dataHotkeys.indexOf(character) >= 0;
  }

  function init() {
    input.removeEventListener('focus', init); // init once
    input.required = true;

    loadScript('{{ "flexsearch.min.js" | absURL }}');

    let path = '{{ (path.Base $searchData.RelPermalink) | absURL}}'
    if(window.curBook === 'manual_history'){
      path = `${ '{{ .Site.BaseURL }}' }${window.curBook}/${window.curVersion}/search-data-${window.curVersion}.js`
    }
    loadScript(path, function () {
      input.required = false;
      search();
    });
  }

  function search() {
    while (results.firstChild) {
      results.removeChild(results.firstChild);
    }

    if (!input.value) {
      clearSearchBtn.classList.remove('display')
      return;
    }

    clearSearchBtn.classList.add('display')
    const curBook = window.curBook === 'manual_history' ? 'manual' : window.curBook
    const searchHits = window.bookSearchIndex.search(input.value, {
      where: {
        book: curBook,
        version: window.curVersion
      }
    });

    if(!searchHits.length){
      results.innerHTML = '<li class="empty">暂无匹配结果</li>'
      return 
    }

    const LiNode = element('<li><a href><div class="title-wrap"><div class="left-line"></div><div class="title"></div></div></a></li>');
    searchHits.forEach(function (page) {
      const li = LiNode.cloneNode(true);
      const a = li.querySelector('a');
      const title = a.querySelector(".title");
      const href = window.curBook === 'manual_history' ? page.href.replace('/manual', `/${window.curBook}/${window.curVersion}`) : page.href
      a.href = `${ '{{.Site.BaseURL}}' }${href}`;

      const matchVal = new RegExp(input.value, 'g')
      title.innerHTML = page.title.replace(matchVal, `<strong>${input.value}</strong>`);

      const idx = page.content && page.content.indexOf(input.value)
      if(idx !== -1){
        const description = element('<div class="description"></div>')
        const maxLength = 40; //默认展示结果为2行，约40字
        const fillLen = Math.floor(maxLength - input.value.length) //填充字符数
        const randomVal = Math.round(fillLen * Math.random())
        const startIdx = idx - randomVal
        const sunstrString = page.content.substr( startIdx > 0 ? startIdx : 0 , 100) //截取100个字，css控制显示2行
        description.innerHTML = sunstrString.replace(matchVal, `<strong>${input.value}</strong>`);
        a.appendChild(description)
      }
      
      results.appendChild(li);
    });
  }

  /**
   * @param {String} src 
   * @param {Function} callback 
   */
  function loadScript(src, callback) {
    const script = document.createElement('script');
    script.defer = true;
    script.async = false;
    script.src = src;
    script.onload = callback;

    document.head.appendChild(script);
  }

  /**
   * @param {String} content
   * @returns {Node}
   */
  function element(content) {
    const div = document.createElement('div');
    div.innerHTML = content;
    return div.firstChild;
  }
})();
